﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace IMCOM.Imagiality.ImageProcessing.Canvas2D.ROI
{
    public class ROIRectangleDrawn : Canvas2DROIState
    {
        private List<RectangleROIHandle> handles;
        private RectangleROIHandle mouseOverROIHandle;

        public new Rectangle ROIRect
        {
            get
            {
                return roiRect;
            }
            set
            {
                roiRect = value;
                controller.Crop(roiRect);
                // possible performance/memory issue -- everytime a resize is performed, handles are re-created.
                FixROIStartAndEndMarkCoordinates();
                createHandles();
            }
        }

        public ROIRectangleDrawn(Canvas2DImageProcessor controller) : base(controller)
        {
            FixROIStartAndEndMarkCoordinates(); // this won't be needed when NormalizedRectangle is implemented
            createHandles();
        }

        public void FixROIStartAndEndMarkCoordinates()
        {
            if (roiRect.Size.Width < 0)
            {
                roiRect = new Rectangle(roiRect.Location.X + roiRect.Size.Width, roiRect.Location.Y, -1 * roiRect.Size.Width, roiRect.Size.Height);
            }
            if (roiRect.Size.Height < 0)
            {
                roiRect = new Rectangle(roiRect.Location.X, roiRect.Location.Y + roiRect.Size.Height, roiRect.Size.Width, -1 * roiRect.Size.Height);
            }
        }
        
        protected void createHandles()
        {
            handles = new List<RectangleROIHandle>();

            // add crosses

            handles.Add(new CrossROIHandle(new Point(roiRect.X, roiRect.Y), true, true));
            handles.Add(new CrossROIHandle(new Point(roiRect.Right, roiRect.Top), true, false));
            handles.Add(new CrossROIHandle(new Point(roiRect.Right, roiRect.Bottom), false, false));
            handles.Add(new CrossROIHandle(new Point(roiRect.Left, roiRect.Bottom), false, true));

            // add verticals
            handles.Add(new VerticalROIHandle(new Point(roiRect.X + roiRect.Width / 2, roiRect.Top), true));
            handles.Add(new VerticalROIHandle(new Point(roiRect.X + roiRect.Width / 2, roiRect.Bottom), false));

            // add horizontals
            handles.Add(new HorizontalROIHandle(new Point(roiRect.Left, roiRect.Top + roiRect.Height / 2), true));
            handles.Add(new HorizontalROIHandle(new Point(roiRect.Right, roiRect.Top + roiRect.Height / 2), false));
        }

        public override void MouseDown(object sender, MouseEventArgs e)
        {
            if (mouseOverROIHandle != null)
            {
                ROIRectangleScaling newState = new ROIRectangleScaling(controller, mouseOverROIHandle);
                newState.ROIRect = roiRect;
                SetControllerState(newState);
            }
            else
            {
                roiRect.Size = new Size(new Point(0, 0));
                controller.RefreshCanvas();
                SetControllerState(new FirstPointSelection(controller));
            }
        }

        public override void MouseUp(object sender, MouseEventArgs e)
        {
        }

        public override void MouseMoved(object sender, MouseEventArgs e)
        {
            bool found = false;
            for (int i = 0; i < handles.Count && !found; i++)
            {
                RectangleROIHandle handle = handles[i];
                if (handle.IsWithinHandle(new Point(e.X, e.Y)))
                {
                    mouseOverROIHandle = handle;
                    found = true;
                    controller.SetCursor(mouseOverROIHandle.GetCursor());
                    controller.RefreshCanvas();
                }
                if (!found)
                {
                    mouseOverROIHandle = null;
                    controller.SetCursor(Cursors.Default);
                }
            }
        }

        public override void ImagePainted(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Rectangle fullRectangle = new Rectangle(0, 0, Convert.ToInt32(g.ClipBounds.Width), Convert.ToInt32(g.ClipBounds.Height));

            if (!roiRect.Size.IsEmpty)
            {
                g.ExcludeClip(roiRect);
                g.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), fullRectangle);
                g.Clip = new Region(fullRectangle);

                foreach (RectangleROIHandle handle in handles)
                    handle.Display(g);
            }
        }
    }
}
